package com.gitee.cui.basic.use;

import com.gitee.cui.util.Print;
import com.gitee.cui.util.ThreadUtil;

/**
 * 线程的等待通知机制
 *
 * @author cuiqingqiang
 * @version 1.0
 * @date 2021-11-20 15:12
 **/
public class WaitNotify {

	/**
	 * 创建一个监视器对象
	 */
	private static final Object lock = new Object();

	static class WaitTarget implements Runnable {

		@Override
		public void run() {
			// 先加锁
			synchronized (lock) {
				try {
					Print.tco("启动等待");
					// 使当前现场等待，放弃CPU的执行权限，线程进入lock监视器的等待列表WaitSet中
					lock.wait();
					// 等待其他线程通知唤醒，线程会进入lock监视器的EntryList中
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				Print.tco("收到通知，当前线程继续执行");
			}
		}
	}

	static class NotifyTarget implements Runnable {

		@Override
		public void run() {
			synchronized (lock) {
				// 通过控制台输入，阻塞当前线程继续执行，使waitTarget线程继续处于等待状态
				Print.consoleInput();
				lock.notifyAll();
				Print.tco("发出通知了，但是线程还没有立马释放");
			}
		}
	}

	public static void main(String[] args) {
		Thread waitTarget = new Thread(new WaitTarget(), "WaitThread");
		waitTarget.start();
		ThreadUtil.sleepMilliSeconds(1000);

		Thread notifyTarget = new Thread(new NotifyTarget(), "NotifyThread");
		notifyTarget.start();

	}
}
